package ems.dev.easycode.sql.builder.impl;

import cn.hutool.core.util.StrUtil;
import ems.dev.easycode.common.FreemarkerEntity;
import ems.dev.easycode.common.SqlTypeEnum;
import ems.dev.easycode.domain.builder.impl.DomainBuilderImpl;
import ems.dev.easycode.domain.entity.ColumnEntity;
import ems.dev.easycode.domain.entity.DomainEntity;
import ems.dev.easycode.domain.entity.TableEntity;
import ems.dev.easycode.sql.builder.SqlBuilder;
import ems.dev.easycode.sql.domain.CRUDSegment;
import ems.dev.easycode.sql.domain.SqlSegmentEntity;
import ems.dev.easycode.util.*;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 狠穿
 * @version 1.0.0
 * @date 2023/5/28
 * @function
 */
public class SqlBuilderImpl implements SqlBuilder {


    /**
     * 生成增删改查的xml文件
     * @param schema
     * @param table
     * @throws SQLException
     */
    private void generateCRUDXmlFile(String schema,String table) throws SQLException {
        TableEntity tableEntity = Db2Util.getTableInfo(schema,table);
        FreemarkerEntity config = new FreemarkerEntity();
        config.setTemplateName("sql.ftl");
        String generateLocation = PropertiesUtil.getProValueStr(Constant.EASY_CODE_PROPERTIES_FILE_NAME, Constant.EASYCODE_GERENATE_LOCATION);
        config.setOutputPath(StrUtil.isBlank(generateLocation)?"C:\\":generateLocation);//不配置默认生成到c盘
        config.setOutputName(tableEntity.getPageNo()+".xml");
        CRUDSegment crudSegment = new CRUDSegment();
        crudSegment.setInsertSeg(insert(schema,table));
        crudSegment.setDeleteSeg(deleteByPrimaryKey(schema,table));
        crudSegment.setUpdateSeg(updateByPrimaryKey(schema,table));
        crudSegment.setSelectSeg(queryByPrimaryKey(schema,table));
        config.setDataSource(crudSegment);
        FreemarkerUtil.generateFinalFile(config);
    }


    /**
     * 生成xml文件
     * @param schema
     * @param table
     */
    public void generateXmlFile(String schema,String table){
        try {
            generateCRUDXmlFile(schema,table);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 组装基于主键进行等值查询的sql字符串
     * @param schema
     * @param table
     * @return
     */
    @Override
    public SqlSegmentEntity queryByPrimaryKey(String schema, String table) throws SQLException {
        SqlSegmentEntity sqlSegmentEntity = new SqlSegmentEntity();
        sqlSegmentEntity.setRemark(xmlComment("基于主键进行等值查询"));
        sqlSegmentEntity.setId("queryByPrimaryKey");
        sqlSegmentEntity.setType(SqlTypeEnum.SELECT);
        TableEntity tableInfo = Db2Util.getTableInfo(schema, table);
        tableInfo.setSchema(SchemaUtil.getSchemaSymbol());
        sqlSegmentEntity.setTable(tableInfo);
        DomainEntity domainInfo = new DomainBuilderImpl().getDomainInfo(schema, table);
        String classFullName = PackageUtil.getClassFullName(domainInfo);
        sqlSegmentEntity.setParameterClass(classFullName);
        sqlSegmentEntity.setResultClass(classFullName);
        return sqlSegmentEntity;
    }

    /**
     * 新增SQL
     * @param schema
     * @param table
     * @return
     * @throws SQLException
     */
    public SqlSegmentEntity insert(String schema, String table) throws SQLException {
        SqlSegmentEntity sqlSegmentEntity = new SqlSegmentEntity();
        sqlSegmentEntity.setRemark(xmlComment("新增"));
        sqlSegmentEntity.setId("insert");
        sqlSegmentEntity.setType(SqlTypeEnum.INSERT);
        TableEntity tableInfo = Db2Util.getTableInfo(schema, table);
        //新增时，更新人和更新时间字段需要剔除
        List<ColumnEntity> collect = tableInfo.getColumns().stream().filter(columnEntity -> {
            String column = columnEntity.getColumn();
            return !StrUtil.equals(column, "REC_REVISOR") && !StrUtil.equals(column, "REC_REVISE_TIME");
        }).collect(Collectors.toList());
        tableInfo.setColumns(collect);
        tableInfo.setSchema(SchemaUtil.getSchemaSymbol());
        sqlSegmentEntity.setTable(tableInfo);
        DomainEntity domainInfo = new DomainBuilderImpl().getDomainInfo(schema, table);
        String classFullName = PackageUtil.getClassFullName(domainInfo);
        sqlSegmentEntity.setParameterClass(classFullName);
        return sqlSegmentEntity;
    }

    /**
     * 根据主键进行删除的SQL组装
     * @param schema
     * @param table
     * @return
     * @throws SQLException
     */
    public SqlSegmentEntity deleteByPrimaryKey(String schema, String table) throws SQLException {
        SqlSegmentEntity sqlSegmentEntity = new SqlSegmentEntity();
        sqlSegmentEntity.setRemark(xmlComment("根据主键删除"));
        sqlSegmentEntity.setId("deleteByPrimaryKey");
        sqlSegmentEntity.setType(SqlTypeEnum.DELETE);
        TableEntity tableInfo = Db2Util.getTableInfo(schema, table);
        tableInfo.setColumns(tableInfo.getColumns());
        tableInfo.setSchema(SchemaUtil.getSchemaSymbol());
        sqlSegmentEntity.setTable(tableInfo);
        DomainEntity domainInfo = new DomainBuilderImpl().getDomainInfo(schema, table);
        sqlSegmentEntity.setParameterClass(PackageUtil.getClassFullName(domainInfo));
        return sqlSegmentEntity;
    }

    /**
     * 根据主键进行修改
     * @param schema
     * @param table
     * @return
     * @throws SQLException
     */
    public SqlSegmentEntity updateByPrimaryKey(String schema, String table) throws SQLException {
        SqlSegmentEntity sqlSegmentEntity = new SqlSegmentEntity();
        sqlSegmentEntity.setRemark(xmlComment("根据主键更新"));
        sqlSegmentEntity.setId("updateByPrimaryKey");
        sqlSegmentEntity.setType(SqlTypeEnum.UPDATE);
        TableEntity tableInfo = Db2Util.getTableInfo(schema, table);
        tableInfo.setColumns(tableInfo.getColumns());
        tableInfo.setSchema(SchemaUtil.getSchemaSymbol());
        sqlSegmentEntity.setTable(tableInfo);
        DomainEntity domainInfo = new DomainBuilderImpl().getDomainInfo(schema, table);
        sqlSegmentEntity.setParameterClass(PackageUtil.getClassFullName(domainInfo));
        return sqlSegmentEntity;
    }

    /**
     * 生成xml格式的注释
     * @param content
     * @return
     */
    private String xmlComment(String content){
        return "<!--"+content+"-->";
    }


    public static void main(String[] args)  {
        new SqlBuilderImpl().generateXmlFile("IPLATHB","T_HD_TAXANDTOTAL_DETAIL");
    }

    @Override
    public void createXml(String tableName) {
       try{
           SqlBuilderImpl sqlBuilder = new SqlBuilderImpl();
           sqlBuilder.generateXmlFile(Db2Util.getCurSchema(),tableName);
       }catch (Exception e){
           throw e;
       }
    }

}

